#include "usart.h"



// 静态全局句柄指针（用于中断处理）
static uart_dma_handle_t *usart1_handle = NULL;
static uart_dma_handle_t *usart2_handle = NULL;
static uart_dma_handle_t *usart3_handle = NULL;

// 环形缓冲区操作实现
void ring_buffer_init(ring_buffer_t *rb, uint8_t *buffer, uint32_t size) {
    rb->buffer = buffer;
    rb->size = size;
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

bool ring_buffer_put(ring_buffer_t *rb, uint8_t data) {
    if (rb->count >= rb->size) {
        return false; // 缓冲区满
    }
    
    rb->buffer[rb->head] = data;
    rb->head = (rb->head + 1) % rb->size;
    rb->count++;
    return true;
}

bool ring_buffer_get(ring_buffer_t *rb, uint8_t *data) {
    if (rb->count == 0) {
        return false; // 缓冲区空
    }
    
    *data = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % rb->size;
    rb->count--;
    return true;
}

uint32_t ring_buffer_count(ring_buffer_t *rb) {
    return rb->count;
}

// 获取默认配置
void usart_dma_get_default_config(uart_dma_config_t *config, USART_TypeDef *usart_instance) {
    config->USARTx = usart_instance;
    config->baudrate = 115200;
    
    // 根据串口实例设置默认DMA和GPIO配置
    if (usart_instance == USART1) {
        config->dma_rx_stream = DMA2_Stream2;
        config->dma_rx_channel = DMA_CHANNEL_4;
        config->dma_tx_stream = DMA2_Stream7;
        config->dma_tx_channel = DMA_CHANNEL_4;
        
        config->tx_gpio_port = GPIOA;
        config->tx_gpio_pin = GPIO_PIN_9;
        config->tx_gpio_af = GPIO_AF7_USART1;
        config->rx_gpio_port = GPIOA;
        config->rx_gpio_pin = GPIO_PIN_10;
        config->rx_gpio_af = GPIO_AF7_USART1;
        
    } else if (usart_instance == USART2) {
        config->dma_rx_stream = DMA1_Stream5;
        config->dma_rx_channel = DMA_CHANNEL_4;
        config->dma_tx_stream = DMA1_Stream6;
        config->dma_tx_channel = DMA_CHANNEL_4;
        
        config->tx_gpio_port = GPIOA;
        config->tx_gpio_pin = GPIO_PIN_2;
        config->tx_gpio_af = GPIO_AF7_USART2;
        config->rx_gpio_port = GPIOA;
        config->rx_gpio_pin = GPIO_PIN_3;
        config->rx_gpio_af = GPIO_AF7_USART2;
        
    } else if (usart_instance == USART3) {
        config->dma_rx_stream = DMA1_Stream1;
        config->dma_rx_channel = DMA_CHANNEL_4;
        config->dma_tx_stream = DMA1_Stream3;
        config->dma_tx_channel = DMA_CHANNEL_4;
        
        config->tx_gpio_port = GPIOB;
        config->tx_gpio_pin = GPIO_PIN_10;
        config->tx_gpio_af = GPIO_AF7_USART3;
        config->rx_gpio_port = GPIOB;
        config->rx_gpio_pin = GPIO_PIN_11;
        config->rx_gpio_af = GPIO_AF7_USART3;
    }
    // 其他串口的默认配置可以类似添加
    
    config->notify_task = NULL;
    config->notify_mask = 0x01;
    config->rx_buffer = NULL;
    config->rx_buffer_size = 0;
}

// USART驱动初始化
usart_dma_status_t usart_dma_init(uart_dma_handle_t *handle) {
    if (handle == NULL || handle->config.rx_buffer == NULL || handle->config.rx_buffer_size == 0) {
        return USART_DMA_INVALID_PARAM;
    }
    
    if (handle->initialized) {
        return USART_DMA_OK;
    }
    
    USART_TypeDef *usart_instance = handle->config.USARTx;
    
    // 使能时钟
    if (usart_instance == USART1) {
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_DMA2_CLK_ENABLE();
        usart1_handle = handle;
    } else if (usart_instance == USART2) {
        __HAL_RCC_USART2_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_DMA1_CLK_ENABLE();
        usart2_handle = handle;
    } else if (usart_instance == USART3) {
        __HAL_RCC_USART3_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        __HAL_RCC_DMA1_CLK_ENABLE();
        usart3_handle = handle;
    }
    // 其他串口类似...
    
    // 配置GPIO
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    // TX引脚配置
    GPIO_InitStruct.Pin = handle->config.tx_gpio_pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = handle->config.tx_gpio_af;
    HAL_GPIO_Init(handle->config.tx_gpio_port, &GPIO_InitStruct);
    
    // RX引脚配置
    GPIO_InitStruct.Pin = handle->config.rx_gpio_pin;
    GPIO_InitStruct.Alternate = handle->config.rx_gpio_af;
    HAL_GPIO_Init(handle->config.rx_gpio_port, &GPIO_InitStruct);
    
    // 配置串口
    handle->huart.Instance = usart_instance;
    handle->huart.Init.BaudRate = handle->config.baudrate;
    handle->huart.Init.WordLength = UART_WORDLENGTH_8B;
    handle->huart.Init.StopBits = UART_STOPBITS_1;
    handle->huart.Init.Parity = UART_PARITY_NONE;
    handle->huart.Init.Mode = UART_MODE_TX_RX;
    handle->huart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    handle->huart.Init.OverSampling = UART_OVERSAMPLING_16;
    
    if (HAL_UART_Init(&handle->huart) != HAL_OK) {
        return USART_DMA_ERROR;
    }
    
    // 配置RX DMA
    handle->hdma_rx.Instance = handle->config.dma_rx_stream;
    handle->hdma_rx.Init.Channel = handle->config.dma_rx_channel;
    handle->hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    handle->hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    handle->hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
    handle->hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    handle->hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    handle->hdma_rx.Init.Mode = DMA_CIRCULAR;
    handle->hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
    handle->hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    handle->hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    handle->hdma_rx.Init.MemBurst = DMA_MBURST_SINGLE;
    handle->hdma_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
    
    if (HAL_DMA_Init(&handle->hdma_rx) != HAL_OK) {
        return USART_DMA_ERROR;
    }
    __HAL_LINKDMA(&handle->huart, hdmarx, handle->hdma_rx);
    
    // 配置TX DMA
    handle->hdma_tx.Instance = handle->config.dma_tx_stream;
    handle->hdma_tx.Init.Channel = handle->config.dma_tx_channel;
    handle->hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    handle->hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    handle->hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
    handle->hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    handle->hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    handle->hdma_tx.Init.Mode = DMA_NORMAL;
    handle->hdma_tx.Init.Priority = DMA_PRIORITY_HIGH;
    handle->hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    handle->hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    handle->hdma_tx.Init.MemBurst = DMA_MBURST_SINGLE;
    handle->hdma_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
    
    if (HAL_DMA_Init(&handle->hdma_tx) != HAL_OK) {
        return USART_DMA_ERROR;
    }
    __HAL_LINKDMA(&handle->huart, hdmatx, handle->hdma_tx);
    
    // 初始化环形缓冲区
    static uint8_t ring_buffer_data[256]; // 静态分配或使用动态内存
    ring_buffer_init(&handle->rx_ring_buffer, ring_buffer_data, sizeof(ring_buffer_data));
    
    // 创建信号量
    handle->tx_semaphore = xSemaphoreCreateBinary();
    if (handle->tx_semaphore == NULL) {
        return USART_DMA_ERROR;
    }
    xSemaphoreGive(handle->tx_semaphore);
    
    // 启动DMA接收
    if (HAL_UART_Receive_DMA(&handle->huart, handle->config.rx_buffer, handle->config.rx_buffer_size) != HAL_OK) {
        return USART_DMA_ERROR;
    }
    
    // 使能空闲中断
    __HAL_UART_ENABLE_IT(&handle->huart, UART_IT_IDLE);
    
    // 设置NVIC优先级并使能中断
    if (usart_instance == USART1) {
        HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
        HAL_NVIC_EnableIRQ(USART1_IRQn);
    } else if (usart_instance == USART2) {
        HAL_NVIC_SetPriority(USART2_IRQn, 5, 0);
        HAL_NVIC_EnableIRQ(USART2_IRQn);
    }
    // 其他串口类似...
    
    handle->dma_rx_last_pos = 0;
    handle->initialized = true;
    
    return USART_DMA_OK;
}

// USART驱动反初始化
usart_dma_status_t usart_dma_deinit(uart_dma_handle_t *handle) {
    if (!handle->initialized) {
        return USART_DMA_OK;
    }
    
    HAL_UART_DeInit(&handle->huart);
    HAL_DMA_DeInit(&handle->hdma_rx);
    HAL_DMA_DeInit(&handle->hdma_tx);
    
    vSemaphoreDelete(handle->tx_semaphore);
    
    handle->initialized = false;
    return USART_DMA_OK;
}

// 发送数据
usart_dma_status_t usart_dma_send(uart_dma_handle_t *handle, const uint8_t *data, uint32_t length, uint32_t timeout) {
    if (!handle->initialized || data == NULL || length == 0) {
        return USART_DMA_INVALID_PARAM;
    }
    
    if (xSemaphoreTake(handle->tx_semaphore, pdMS_TO_TICKS(timeout)) != pdTRUE) {
        return USART_DMA_TIMEOUT;
    }
    
    if (HAL_UART_Transmit_DMA(&handle->huart, (uint8_t*)data, length) != HAL_OK) {
        xSemaphoreGive(handle->tx_semaphore);
        return USART_DMA_ERROR;
    }
    
    return USART_DMA_OK;
}

// 读取数据
uint32_t usart_dma_read(uart_dma_handle_t *handle, uint8_t *buffer, uint32_t max_length) {
    if (!handle->initialized || buffer == NULL || max_length == 0) {
        return 0;
    }
    
    uint32_t bytes_read = 0;
    
    while (bytes_read < max_length && ring_buffer_count(&handle->rx_ring_buffer) > 0) {
        if (ring_buffer_get(&handle->rx_ring_buffer, &buffer[bytes_read])) {
            bytes_read++;
        } else {
            break;
        }
    }
    
    return bytes_read;
}

// 获取接收缓冲区中的数据数量
uint32_t usart_dma_get_rx_count(uart_dma_handle_t *handle) {
    if (!handle->initialized) {
        return 0;
    }
    
    return ring_buffer_count(&handle->rx_ring_buffer);
}

// 清空接收缓冲区
void usart_dma_clear_rx_buffer(uart_dma_handle_t *handle) {
    if (handle->initialized) {
        ring_buffer_init(&handle->rx_ring_buffer, 
                        handle->rx_ring_buffer.buffer, 
                        handle->rx_ring_buffer.size);
    }
}

// DMA发送完成回调
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
    if (usart1_handle != NULL && huart->Instance == usart1_handle->huart.Instance) {
        xSemaphoreGive(usart1_handle->tx_semaphore);
    } else if (usart2_handle != NULL && huart->Instance == usart2_handle->huart.Instance) {
        xSemaphoreGive(usart2_handle->tx_semaphore);
    } else if (usart3_handle != NULL && huart->Instance == usart3_handle->huart.Instance) {
        xSemaphoreGive(usart3_handle->tx_semaphore);
    }
}

// 空闲中断处理函数
static void usart_idle_irq_handler(uart_dma_handle_t *handle) {
    if (__HAL_UART_GET_FLAG(&handle->huart, UART_FLAG_IDLE)) {
        __HAL_UART_CLEAR_IDLEFLAG(&handle->huart);
        
        // 计算接收到的数据长度
        uint32_t received_length = handle->config.rx_buffer_size - __HAL_DMA_GET_COUNTER(&handle->hdma_rx);
        
        if (received_length > 0) {
            // 将数据从DMA缓冲区复制到环形缓冲区
            for (uint32_t i = 0; i < received_length; i++) {
                uint32_t index = (handle->dma_rx_last_pos + i) % handle->config.rx_buffer_size;
                ring_buffer_put(&handle->rx_ring_buffer, handle->config.rx_buffer[index]);
            }
            
            handle->dma_rx_last_pos = (handle->dma_rx_last_pos + received_length) % handle->config.rx_buffer_size;
            
            // 通知上层任务
            if (handle->config.notify_task != NULL) {
                xTaskNotify(handle->config.notify_task, handle->config.notify_mask, eSetBits);
            }
        }
    }
}

// 中断处理函数
void USART1_IRQHandler(void) {
    if (usart1_handle != NULL) {
        usart_idle_irq_handler(usart1_handle);
        HAL_UART_IRQHandler(&usart1_handle->huart);
    }
}

void USART2_IRQHandler(void) {
    if (usart2_handle != NULL) {
        usart_idle_irq_handler(usart2_handle);
        HAL_UART_IRQHandler(&usart2_handle->huart);
    }
}

void USART3_IRQHandler(void) {
    if (usart3_handle != NULL) {
        usart_idle_irq_handler(usart3_handle);
        HAL_UART_IRQHandler(&usart3_handle->huart);
    }
}

// DMA中断处理函数
void DMA2_Stream2_IRQHandler(void) {
    if (usart1_handle != NULL) {
        HAL_DMA_IRQHandler(&usart1_handle->hdma_rx);
    }
}

void DMA2_Stream7_IRQHandler(void) {
    if (usart1_handle != NULL) {
        HAL_DMA_IRQHandler(&usart1_handle->hdma_tx);
    }
}
